﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Fast.Framework.Interfaces;
using Fast.Framework.Extensions;
using Fast.Framework.Models;


namespace Fast.Framework
{

    #region Query1
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class QueryProvider<T> : IQuery<T>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// 查询构造者
        /// </summary>
        public IQueryBuilder QueryBuilder { get; }

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public QueryProvider(IAdo ado, IQueryBuilder queryBuilder)
        {
            this.ado = ado;
            QueryBuilder = queryBuilder;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 插入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IQuery<T> Insert<TInsert>()
        {
            var type = typeof(TInsert);
            return Insert(type.GetTableName(), type.GetColumnName());
        }

        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="tableName">表名称</param>
        /// <param name="colums">列</param>
        /// <returns></returns>
        public IQuery<T> Insert(string tableName, List<string> colums)
        {
            if (!colums.Any())
            {
                throw new ArgumentNullException(nameof(colums));
            }
            QueryBuilder.InsertTable = DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, tableName);
            QueryBuilder.InsertColumns = string.Join(",\r\n", colums.Select(s => DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, s)));
            return this;
        }

        /// <summary>
        /// 插入
        /// </summary>
        /// <typeparam name="TInsert"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T> Insert<TInsert>(Expression<Func<TInsert, object>> expression)
        {
            QueryBuilder.InsertTable = DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(TInsert).GetTableName());
            var sqlInfo = expression.ResolveSql(new SqlExpressionOptions() { DbType = ado.DbOptions.DbType, IgnoreParameterExpression = true });
            if (sqlInfo.SqlStack.Count > 0)
            {
                sqlInfo.NewNames.Add(string.Join("", sqlInfo.SqlStack.ToList()));
            }
            QueryBuilder.InsertColumns = string.Join(",\r\n", sqlInfo.NewNames);
            return this;
        }

        /// <summary>
        /// 作为
        /// </summary>
        /// <param name="tableName">表名称</param>
        /// <returns></returns>
        public IQuery<T> As(string tableName)
        {
            if (string.IsNullOrWhiteSpace(tableName))
            {
                QueryBuilder.TableName = "";
            }
            else
            {
                QueryBuilder.TableName = $"{DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, tableName)} p{QueryBuilder.Join.Count}";
            }
            return this;
        }

        /// <summary>
        /// 不同
        /// </summary>
        /// <returns></returns>
        public IQuery<T> Distinct()
        {
            QueryBuilder.Distinct = true;
            return this;
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T2"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2> LeftJoin<T2>(Expression<Func<T, T2, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T2).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T2"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2> InnerJoin<T2>(Expression<Func<T, T2, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T2).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T> Where(Expression<Func<T, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="inFieldsName">In字段名称</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T> In<FieldsType>(string inFieldsName, params FieldsType[] values)
        {
            return In(inFieldsName, values.ToList());
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="inFieldsName">In字段名称</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T> In<FieldsType>(string inFieldsName, List<FieldsType> values)
        {
            var type = typeof(FieldsType);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add($"{DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, inFieldsName)} IN ({string.Join(",", sqlParameters.Keys.Select(s => $"{DbSymbolMapper.parameter[ado.DbOptions.DbType]}{s}"))})");
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T> In<FieldsType>(Expression<Func<T, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="notInFieldsName">Not In字段名称</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T> NotIn<FieldsType>(string notInFieldsName, params FieldsType[] values)
        {
            return In(notInFieldsName, values.ToList());
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="notInFieldsName">Not In字段名称</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T> NotIn<FieldsType>(string notInFieldsName, List<FieldsType> values)
        {
            var type = typeof(FieldsType);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add($"{DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, notInFieldsName)} NOT IN ({string.Join(",", sqlParameters.Keys.Select(s => $"{DbSymbolMapper.parameter[ado.DbOptions.DbType]}{s}"))})");
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T> NotIn<FieldsType>(Expression<Func<T, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T> GroupBy(Expression<Func<T, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T> Having(Expression<Func<T, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="orderFileds">排序字段</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T> OrderBy(string orderFileds, string orderType = "ASC")
        {
            QueryBuilder.Order.Add($"{orderFileds} {orderType}");
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T> OrderBy(Expression<Func<T, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }

        /// <summary>
        /// 执行异步
        /// </summary>
        /// <returns></returns>
        public Task<int> ExecuteAsync()
        {
            return ado.ExecuteNonQueryAsync(this.ToString(), ado.SqlParametersBuild(QueryBuilder.Parameters));
        }

        /// <summary>
        /// 字典异步
        /// </summary>
        /// <returns></returns>
        public Task<Dictionary<string, object>> DictionaryAsync()
        {
            return ado.ExecuteReaderAsync(this.ToString(), ado.SqlParametersBuild(QueryBuilder.Parameters)).DictionaryBuildAsync();
        }

        /// <summary>
        /// 字典列表异步
        /// </summary>
        /// <returns></returns>
        public Task<List<Dictionary<string, object>>> DictionaryListAsync()
        {
            return ado.ExecuteReaderAsync(this.ToString(), ado.SqlParametersBuild(QueryBuilder.Parameters)).DictionaryListBuildAsync();
        }

        /// <summary>
        /// 第一异步
        /// </summary>
        /// <returns></returns>
        public Task<T> FirstAsync()
        {
            return ado.ExecuteReaderAsync(this.ToString(), ado.SqlParametersBuild(QueryBuilder.Parameters)).FristBuildAsync<T>();
        }

        /// <summary>
        /// 到列表异步
        /// </summary>
        /// <returns></returns>
        public Task<List<T>> ToListAsync()
        {
            return ado.ExecuteReaderAsync(this.ToString(), ado.SqlParametersBuild(QueryBuilder.Parameters)).ListBuildAsync<T>();
        }

        /// <summary>
        /// 到分页列表
        /// </summary>
        /// <param name="page">页</param>
        /// <param name="pageSize">页大小</param>
        /// <returns></returns>
        public async Task<PageData<List<T>>> ToPageListAsync(int page, int pageSize)
        {
            string pageSql;
            if (ado.DbOptions.DbType == DbType.SQLServer)
            {
                QueryBuilder.Columns = QueryBuilder.Columns.Insert(0, "ROW_NUMBER() OVER (ORDER BY (SELECT 0)) row_id,");
                pageSql = string.Format("SELECT * FROM ( \r\n{0}\r\n ) x WHERE x.row_id BETWEEN {1} AND {2}", this.ToString(), (page - 1) * pageSize + 1, page * pageSize);
            }
            else if (ado.DbOptions.DbType == DbType.Oracle)
            {
                pageSql = string.Format("SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY 0) \"row_id\",\"x\".* FROM ({0}) \"x\") \"x\" WHERE \"x\".\"row_id\" BETWEEN {1} AND {2}", this.ToString(), (page - 1) * pageSize + 1, page * pageSize);
            }
            else if (ado.DbOptions.DbType == DbType.MySQL || ado.DbOptions.DbType == DbType.PostgreSQL || ado.DbOptions.DbType == DbType.SQLite)
            {
                pageSql = string.Format("SELECT * FROM ( \r\n{0}\r\n ) x LIMIT {1} OFFSET {2}", this.ToString(), pageSize, (page - 1) * pageSize);
            }
            else
            {
                throw new NotSupportedException($"{ado.DbOptions.DbType} 不支持的数据库类型");
            }
            var data = await ado.ExecuteReaderAsync(pageSql, ado.SqlParametersBuild(QueryBuilder.Parameters)).ListBuildAsync<T>();
            var count = await CountAsync();
            return new PageData<List<T>>() { Data = data, Count = count };
        }

        /// <summary>
        /// 计数
        /// </summary>
        /// <returns></returns>
        public Task<int> CountAsync()
        {
            QueryBuilder.Columns = "COUNT(1) AS Count";
            return ado.ExecuteScalarAsync<int>(this.ToString(), ado.SqlParametersBuild(QueryBuilder.Parameters));
        }

        /// <summary>
        /// 任何异步
        /// </summary>
        /// <returns></returns>
        public async Task<bool> AnyAsync()
        {
            return await CountAsync() > 0;
        }

        /// <summary>
        /// 转换字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return QueryBuilder.ToString();
        }
    }
    #endregion

    #region Query2
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    public class Query<T, T2> : QueryProvider<T>, IQuery<T, T2>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T3"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3> LeftJoin<T3>(Expression<Func<T, T2, T3, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T3).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T3"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3> InnerJoin<T3>(Expression<Func<T, T2, T3, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T3).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2> Where(Expression<Func<T, T2, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2> In<FieldsType>(Expression<Func<T, T2, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2> NotIn<FieldsType>(Expression<Func<T, T2, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2> GroupBy(Expression<Func<T, T2, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2> Having(Expression<Func<T, T2, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2> OrderBy(Expression<Func<T, T2, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query3
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    public class Query<T, T2, T3> : Query<T, T2>, IQuery<T, T2, T3>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T4"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4> LeftJoin<T4>(Expression<Func<T, T2, T3, T4, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T4).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T4"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4> InnerJoin<T4>(Expression<Func<T, T2, T3, T4, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T4).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3> Where(Expression<Func<T, T2, T3, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3> In<FieldsType>(Expression<Func<T, T2, T3, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3> NotIn<FieldsType>(Expression<Func<T, T2, T3, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3> GroupBy(Expression<Func<T, T2, T3, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3> Having(Expression<Func<T, T2, T3, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3> OrderBy(Expression<Func<T, T2, T3, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query4
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    public class Query<T, T2, T3, T4> : Query<T, T2, T3>, IQuery<T, T2, T3, T4>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T5"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5> LeftJoin<T5>(Expression<Func<T, T2, T3, T4, T5, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T5).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T5"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5> InnerJoin<T5>(Expression<Func<T, T2, T3, T4, T5, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T5).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4> Where(Expression<Func<T, T2, T3, T4, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4> In<FieldsType>(Expression<Func<T, T2, T3, T4, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4> NotIn<FieldsType>(Expression<Func<T, T2, T3, T4, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4> GroupBy(Expression<Func<T, T2, T3, T4, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4> Having(Expression<Func<T, T2, T3, T4, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4> OrderBy(Expression<Func<T, T2, T3, T4, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, T4, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query5
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    public class Query<T, T2, T3, T4, T5> : Query<T, T2, T3, T4>, IQuery<T, T2, T3, T4, T5>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T6"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6> LeftJoin<T6>(Expression<Func<T, T2, T3, T4, T5, T6, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T6).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T6"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6> InnerJoin<T6>(Expression<Func<T, T2, T3, T4, T5, T6, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T6).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5> Where(Expression<Func<T, T2, T3, T4, T5, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5> In<FieldsType>(Expression<Func<T, T2, T3, T4, T5, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5> NotIn<FieldsType>(Expression<Func<T, T2, T3, T4, T5, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5> GroupBy(Expression<Func<T, T2, T3, T4, T5, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5> Having(Expression<Func<T, T2, T3, T4, T5, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5> OrderBy(Expression<Func<T, T2, T3, T4, T5, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, T4, T5, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query6
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    public class Query<T, T2, T3, T4, T5, T6> : Query<T, T2, T3, T4, T5>, IQuery<T, T2, T3, T4, T5, T6>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T7"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7> LeftJoin<T7>(Expression<Func<T, T2, T3, T4, T5, T6, T7, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T7).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T7"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7> InnerJoin<T7>(Expression<Func<T, T2, T3, T4, T5, T6, T7, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T7).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6> Where(Expression<Func<T, T2, T3, T4, T5, T6, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6> In<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6> NotIn<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6> GroupBy(Expression<Func<T, T2, T3, T4, T5, T6, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6> Having(Expression<Func<T, T2, T3, T4, T5, T6, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6> OrderBy(Expression<Func<T, T2, T3, T4, T5, T6, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, T4, T5, T6, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query7
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="T7"></typeparam>
    public class Query<T, T2, T3, T4, T5, T6, T7> : Query<T, T2, T3, T4, T5, T6>, IQuery<T, T2, T3, T4, T5, T6, T7>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T8"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8> LeftJoin<T8>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T8).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T8"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8> InnerJoin<T8>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T8).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7> Where(Expression<Func<T, T2, T3, T4, T5, T6, T7, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7> In<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7> NotIn<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7> GroupBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7> Having(Expression<Func<T, T2, T3, T4, T5, T6, T7, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7> OrderBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, T4, T5, T6, T7, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query8
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="T7"></typeparam>
    /// <typeparam name="T8"></typeparam>
    public class Query<T, T2, T3, T4, T5, T6, T7, T8> : Query<T, T2, T3, T4, T5, T6, T7>, IQuery<T, T2, T3, T4, T5, T6, T7, T8>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T9"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9> LeftJoin<T9>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T9).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8, T9>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T9"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9> InnerJoin<T9>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T9).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8, T9>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8> Where(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8> In<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8> NotIn<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8> GroupBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8> Having(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8> OrderBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query9
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="T7"></typeparam>
    /// <typeparam name="T8"></typeparam>
    /// <typeparam name="T9"></typeparam>
    public class Query<T, T2, T3, T4, T5, T6, T7, T8, T9> : Query<T, T2, T3, T4, T5, T6, T7, T8>, IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T10"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> LeftJoin<T10>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T10).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T10"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> InnerJoin<T10>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T10).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9> Where(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9> In<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9> NotIn<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9> GroupBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9> Having(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9> OrderBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query10
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="T7"></typeparam>
    /// <typeparam name="T8"></typeparam>
    /// <typeparam name="T9"></typeparam>
    /// <typeparam name="T10"></typeparam>
    public class Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> : Query<T, T2, T3, T4, T5, T6, T7, T8, T9>, IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T11"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> LeftJoin<T11>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T11).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T11"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> InnerJoin<T11>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T11).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> Where(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> In<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> NotIn<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> GroupBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> Having(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10> OrderBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query11
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="T7"></typeparam>
    /// <typeparam name="T8"></typeparam>
    /// <typeparam name="T9"></typeparam>
    /// <typeparam name="T10"></typeparam>
    /// <typeparam name="T11"></typeparam>
    public class Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> : Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10>, IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 左连接
        /// </summary>
        /// <typeparam name="T12"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> LeftJoin<T12>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"LEFT JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T12).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 内连接
        /// </summary>
        /// <typeparam name="T12"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> InnerJoin<T12>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Join.Add($"INNER JOIN {DbSymbolMapper.identify[ado.DbOptions.DbType].Insert(1, typeof(T12).GetTableName())} p{QueryBuilder.Join.Count + 1} ON {sqlInfo.WhereFormat()}");
            var query = new Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(ado, QueryBuilder);
            return query;
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Where(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> In<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> NotIn<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> GroupBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Having(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> OrderBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion

    #region Query12
    /// <summary>
    /// 查询实现类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="T2"></typeparam>
    /// <typeparam name="T3"></typeparam>
    /// <typeparam name="T4"></typeparam>
    /// <typeparam name="T5"></typeparam>
    /// <typeparam name="T6"></typeparam>
    /// <typeparam name="T7"></typeparam>
    /// <typeparam name="T8"></typeparam>
    /// <typeparam name="T9"></typeparam>
    /// <typeparam name="T10"></typeparam>
    /// <typeparam name="T11"></typeparam>
    /// <typeparam name="T12"></typeparam>
    public class Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> : Query<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>, IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>
    {

        /// <summary>
        /// Ado
        /// </summary>
        private readonly IAdo ado;

        /// <summary>
        /// Sql表达式选项
        /// </summary>
        private readonly SqlExpressionOptions sqlExpressionOptions;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="ado">ado</param>
        /// <param name="queryBuilder">查询建造者</param>
        public Query(IAdo ado, IQueryBuilder queryBuilder) : base(ado, queryBuilder)
        {
            this.ado = ado;
            sqlExpressionOptions = new SqlExpressionOptions()
            {
                DbType = ado.DbOptions.DbType
            };
        }

        /// <summary>
        /// 条件
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Where(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, bool>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Where.Add(sqlInfo.WhereFormat());
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return this;
        }

        /// <summary>
        /// In条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> In<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.InFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// NotIn条件
        /// </summary>
        /// <typeparam name="FieldsType">字段类型</typeparam>
        /// <param name="expression">表达式</param>
        /// <param name="values">值</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> NotIn<FieldsType>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, object>> expression, List<FieldsType> values)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var sqlParameters = new Dictionary<string, FieldsType>().AddIdentityKey(values, QueryBuilder.Parameters.Count);
            QueryBuilder.Where.Add(sqlInfo.NotInFormat(DbSymbolMapper.parameter[ado.DbOptions.DbType], sqlParameters));
            QueryBuilder.Parameters.Append(sqlParameters);
            return this;
        }

        /// <summary>
        /// 分组
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> GroupBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, object>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            var str = sqlInfo.NewValuesFormat();
            QueryBuilder.Columns = str;
            QueryBuilder.Group = str;
            return this;
        }

        /// <summary>
        /// 有
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Having(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, bool>> expression)
        {
            if (string.IsNullOrWhiteSpace(QueryBuilder.Group))
            {
                throw new Exception("必须包含分组查询才能使用Having");
            }
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Having.Add(sqlInfo.WhereFormat());
            return this;
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="orderType">排序类型</param>
        /// <returns></returns>
        public IQuery<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> OrderBy(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, object>> expression, string orderType = "ASC")
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Order.Add($"{sqlInfo.NewValuesFormat()} {orderType}");
            return this;
        }

        /// <summary>
        /// 选择
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="expression">表达式</param>
        /// <returns></returns>
        public IQuery<TResult> Select<TResult>(Expression<Func<T, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>> expression)
        {
            var sqlInfo = expression.ResolveSql(sqlExpressionOptions);
            QueryBuilder.Columns = sqlInfo.NewAsFormat();
            QueryBuilder.Parameters.Append(sqlInfo.SqlParameters);
            return new QueryProvider<TResult>(ado, QueryBuilder);
        }
    }
    #endregion
}
